#include "pch.h"
#include "GaojieLogApp.h"
#include "LogManager.h"
#include "..\Common\SRWLock.h"
#include "..\Common\Utility.h"

CGaojieLogApp::CGaojieLogApp()
	: m_logLevel(LogLevel::Info)
{
}

CGaojieLogApp::~CGaojieLogApp()
{
	assert(!m_pLogManager);
}

bool CGaojieLogApp::Init(LPCVOID lpAddress)
{
	AssertInUIThread();
	assert(!m_pLogManager);

	LoadConfig();

	CExclusiveLock lock(m_SRWLock);
	m_pLogManager = std::make_unique<CLogManager>();

	if (!m_pLogManager->Init())
		return false;

	// Output log level first
	if (m_logLevel != LogLevel::Off)
	{
		std::string strLine = "LogInit: Level=";

		switch (m_logLevel)
		{
		case LogLevel::Error:
			strLine += "Error";
			break;

		case LogLevel::Warn:
			strLine += "Warn";
			break;

		case LogLevel::Info:
			strLine += "Info";
			break;
		}

		m_pLogManager->WriteLine(lpAddress, strLine);
	}

	return true;
}

void CGaojieLogApp::Exit(LPCVOID lpAddress)
{
	AssertInUIThread();

	CExclusiveLock lock(m_SRWLock);
	auto pLogManager = std::move(m_pLogManager);
	lock.Unlock();

	if (pLogManager)
	{
		if (m_logLevel != LogLevel::Off)
			pLogManager->WriteLine(lpAddress, "LogExit");

		pLogManager->Exit();
	}
}

bool CGaojieLogApp::IsLoggable(LogLevel logLevel) const
{
	return logLevel <= m_logLevel;
}

void CGaojieLogApp::WriteLine(LPCVOID lpAddress, const std::string& strLine)
{
	CSharedLock lock(m_SRWLock);

	if (m_pLogManager)
		m_pLogManager->WriteLine(lpAddress, strLine);
}

void CGaojieLogApp::LoadConfig()
{
	AssertInUIThread();

	std::wstring strFileName;
	if (!Util::GetConfigFile(strFileName))
		return;

	wchar_t szBuffer[16];
	if (GetPrivateProfileStringW(L"Main", L"LogLevel", NULL, szBuffer, ARRAYSIZE(szBuffer), strFileName.c_str()) == 0)
		return;

	if (_wcsnicmp(szBuffer, L"Error", 5) == 0)
		m_logLevel = LogLevel::Error;
	else if (_wcsnicmp(szBuffer, L"Warn", 4) == 0)
		m_logLevel = LogLevel::Warn;
	else if (_wcsnicmp(szBuffer, L"Info", 4) == 0)
		m_logLevel = LogLevel::Info;
	else
		m_logLevel = LogLevel::Off;
}
